﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Autofac;
using HomeDump.Server.Data;
using HomeDump.Server.Components.MusicSearch;
using NLog;
using IContainer = Autofac.IContainer;

namespace HomeDump.Server
{
	/// <summary>
	/// Entry point for the application.
	/// </summary>
	internal class Program
	{
		private static readonly Logger Log = LogManager.GetCurrentClassLogger();


		/// <summary>
		/// Main method acting as entry point for the application.
		/// </summary>
		private static void Main()
		{
			IContainer container = BuildContainer();

			CleanDatabase();

			AddTracks(container);

			PrintNumberOfTracks();

			Console.ReadKey();
		}


		private static void CleanDatabase()
		{
			Console.Write("Cleaning database... ");

			using (var db = new MusicContext())
			{
				// Delete tracks
				foreach (var track in db.Tracks)
				{
					db.Tracks.DeleteObject(track);
				}

				// Delete artists
				foreach (var artist in db.Artists)
				{
					db.Artists.DeleteObject(artist);
				}

				// Delete albums
				foreach (var album in db.Albums)
				{
					db.Albums.DeleteObject(album);
				}

				db.SaveChanges();
			}

			Console.WriteLine("Done!");
		}


		private static void AddTracks(IContainer container)
		{
			Console.Write("Adding tracks... ");

			var musciPath = container.Resolve<IMusicPath>();

			Task<IEnumerable<MusicFile>> musicFilesTask =
				musciPath.SearchForMusicFilesAsync(@"C:\Users\Public\Music\Sample Music");

			musicFilesTask.Wait();

			if (musicFilesTask.Status == TaskStatus.RanToCompletion)
			{
				using (var db = new MusicContext())
				{
					foreach (var musicFile in musicFilesTask.Result)
					{
						Artist artist =
							db.Artists.SingleOrDefault(a => a.Name == musicFile.Artist) ??
							new Artist { Name = musicFile.Artist };

						Album album =
							db.Albums.SingleOrDefault(a => a.Name == musicFile.Album) ??
								new Album { Name = musicFile.Album };

						var track = new Track
						{
							Name = musicFile.Name,
							Artist = artist,
							Album = album,
							Duration = musicFile.Duration
						};

						db.Tracks.AddObject(track);
						db.SaveChanges();
					}
				}

				Console.WriteLine("Done!");
			}
			else
			{
				Console.WriteLine("FAILED!");
			}
		}


		private static void PrintNumberOfTracks()
		{
			using (var db = new MusicContext())
			{
				Console.WriteLine("Tracks: {0}", db.Tracks.Count());
				Console.WriteLine("Artists: {0}", db.Artists.Count());
				Console.WriteLine("Albums: {0}", db.Albums.Count());
			}
		}


		/// <summary>
		/// Builds the container using Autofac.
		/// </summary>
		private static IContainer BuildContainer()
		{
			Log.Debug("Creating container builder");
			var builder = new ContainerBuilder();

			// Register server module
			builder.RegisterModule(new ServerModule());

			Log.Debug("Building container");
			return builder.Build();
		}
	}
}
